#ifndef NET_CONNECTION_H
#define NET_CONNECTION_H

#include <memory>
#include <functional>
#include <cstdint>
#include "logger.h"
#include "socket.h"
#include "buffer.h"
#include "channel.h"
#include "event_loop.h"
#include "any.h"

namespace net {

// 连接状态枚举
typedef enum {
    DISCONNECTED,  // 连接关闭状态
    CONNECTING,    // 连接建立中（待初始化）
    CONNECTED,     // 连接就绪（可通信）
    DISCONNECTING  // 待关闭状态（处理剩余数据）
} ConnStatu;

class Connection;
// 连接智能指针类型（便于生命周期管理）
using PtrConnection = std::shared_ptr<Connection>;

/**
 * @brief 连接管理类，封装TCP连接的完整生命周期
 * 负责数据收发、事件处理、状态管理及回调触发
 */
class Connection : public std::enable_shared_from_this<Connection> 
{
public:
    // 回调函数类型定义
    using ConnectedCallback = std::function<void(const PtrConnection&)>;        // 连接建立回调
    using MessageCallback = std::function<void(const PtrConnection&, Buffer*)>; // 消息接收回调
    using ClosedCallback = std::function<void(const PtrConnection&)>;           // 连接关闭回调（用户层）
    using AnyEventCallback = std::function<void(const PtrConnection&)>;         // 任意事件回调

    /**
     * @brief 构造函数
     * @param loop 所属事件循环
     * @param conn_id 连接唯一ID
     * @param sockfd 连接对应的套接字描述符
     */
    Connection(EventLoop* loop, uint64_t connId, int sockfd);

    /**
     * @brief 析构函数
     */
    ~Connection();

    // 禁止拷贝和移动（由智能指针管理）
    Connection(const Connection&) = delete;
    Connection& operator=(const Connection&) = delete;
    Connection(Connection&&) = delete;
    Connection& operator=(Connection&&) = delete;

    /**
     * @brief 获取套接字描述符
     * @return 套接字描述符
     */
    int fd() const { return _sockfd; }

    /**
     * @brief 获取连接唯一ID
     * @return 连接ID
     */
    uint64_t id() const { return _connId; }

    /**
     * @brief 判断连接是否处于就绪状态
     * @return 就绪返回true，否则返回false
     */
    bool connected() const { return _statu == CONNECTED; }

    /**
     * @brief 设置连接上下文（存储业务数据）
     * @param context 任意类型的上下文数据
     */
    void setContext(const util::Any& context) { _context = context; }

    /**
     * @brief 获取连接上下文
     * @return 上下文数据指针
     */
    util::Any* getContext() { return &_context; }

    // 设置回调函数
    void setConnectedCallback(const ConnectedCallback& cb) { _connectedCallback = cb; }
    void setMessageCallback(const MessageCallback& cb) { _messageCallback = cb; }
    void setClosedCallback(const ClosedCallback& cb) { _closedCallback = cb; }
    void setAnyEventCallback(const AnyEventCallback& cb) { _eventCallback = cb; }
    void setSrvClosedCallback(const ClosedCallback& cb) { _serverClosedCallback = cb; }

    /**
     * @brief 标记连接建立完成（启动事件监控并触发回调）
     */
    void established();

    /**
     * @brief 发送数据（线程安全）
     * @param data 待发送数据
     * @param len 数据长度
     */
    void send(const char* data, size_t len);

    /**
     * @brief 开始关闭连接（处理剩余数据后释放）
     */
    void shutdown();

    /**
     * @brief 释放连接（实际执行关闭操作）
     */
    void release();

    /**
     * @brief 启动非活跃连接自动释放（超时无事件则关闭）
     * @param sec 超时时间（秒）
     */
    void enableInactiveRelease(int sec);

    /**
     * @brief 取消非活跃连接自动释放
     */
    void cancelInactiveRelease();

    /**
     * @brief 切换连接协议/上下文（如HTTP升级为WebSocket）
     * @param context 新的上下文数据
     * @param conn 新的连接建立回调
     * @param msg 新的消息回调
     * @param closed 新的关闭回调
     * @param event 新的任意事件回调
     */
    void upgrade(const util::Any& context, 
                const ConnectedCallback& conn, 
                const MessageCallback& msg, 
                const ClosedCallback& closed, 
                const AnyEventCallback& event);

private:
    // 事件处理函数（Channel回调）
    void handleRead();    // 读事件处理（接收数据）
    void handleWrite();   // 写事件处理（发送数据）
    void handleClose();   // 关闭事件处理
    void handleError();   // 错误事件处理
    void handleEvent();   // 任意事件处理（刷新活跃度）

    // 内部实现函数（确保在事件循环线程执行）
    void establishedInLoop();               // 初始化连接（事件循环内）
    void sendInLoop(Buffer& buf);           // 发送数据（事件循环内）
    void shutdownInLoop();                  // 关闭准备（事件循环内）
    void releaseInLoop();                   // 释放连接（事件循环内）
    void enableInactiveReleaseInLoop(int sec); // 启动非活跃释放（事件循环内）
    void cancelInactiveReleaseInLoop();     // 取消非活跃释放（事件循环内）
    void upgradeInLoop(const util::Any& context, 
                      const ConnectedCallback& conn, 
                      const MessageCallback& msg, 
                      const ClosedCallback& closed, 
                      const AnyEventCallback& event); // 切换协议（事件循环内）

private:
    uint64_t _connId;                   // 连接唯一ID
    int _sockfd;                        // 套接字描述符
    bool _enableInactiveRelease;        // 是否启用非活跃释放
    EventLoop* _loop;                   // 所属事件循环
    ConnStatu _statu;                   // 连接状态
    std::unique_ptr<Socket> _socket;    // 套接字封装
    std::unique_ptr<Channel> _channel;  // 事件通道（管理套接字事件）
    Buffer _inBuffer;                   // 输入缓冲区（接收数据）
    Buffer _outBuffer;                  // 输出缓冲区（发送数据）
    util::Any _context;                 // 业务上下文数据

    // 回调函数 
    ConnectedCallback _connectedCallback;       // 连接建立回调
    MessageCallback _messageCallback;           // 消息接收回调
    ClosedCallback _closedCallback;             // 关闭回调（用户层）
    AnyEventCallback _eventCallback;            // 任意事件回调
    ClosedCallback _serverClosedCallback;       // 关闭回调（框架层，用于移除连接）
};

} // namespace net

#endif // NET_CONNECTION_H